package cn.edu.ctgu;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**.
 * 问卷服务类，管理问卷问题和提供建议
 */
public class QuestionnaireService {
    private final Map<String, List<Question>> questionMap = new HashMap<>();

    // 定义常量，避免魔术数字
    private static final double MIN_TEMPERATURE = 37.3;
    private static final double MAX_TEMPERATURE = 42;
    private static final double TEMPERATURE_STEP = 0.1;

    // 新增整数形式的温度常量（用于循环计数）
    private static final int MIN_TEMPERATURE_INT = 373;  // 对应37.3℃（乘以10）
    private static final int MAX_TEMPERATURE_INT = 420;  // 对应42.0℃（乘以10）
    private static final double TEMPERATURE_DIVIDER = 10.0;  // 用于转换回小数的除数

    /**.
     * 构造函数，用于初始化问卷服务。
     * 在创建 QuestionnaireService 实例时，此构造函数会调用 initializeAllQuestions 方法，
     * 该方法会初始化所有的问卷问题并将其存储在 questionMap 中。
     */
    public QuestionnaireService() {
        initializeAllQuestions();
    }

    /**.
     * 初始化所有问卷问题
     */
    private void initializeAllQuestions() {
        questionMap.put("症状采集", initializeSymptomQuestions());
        questionMap.put("发热", initializeFeverQuestions());
        questionMap.put("咳嗽", initializeCoughQuestions());
        questionMap.put("腹泻", initializeDiarrheaQuestions());
        questionMap.put("胸闷", initializeChestTightnessQuestions());
        questionMap.put("气急", initializeShortnessOfBreathQuestions());
        questionMap.put("症状时长", initializeDurationQuestions());
        questionMap.put("接触史", initializeContactHistoryQuestions());
    }

    /**.
     * 初始化症状采集问题
     *
     * @return 症状采集问题列表
     */
    private List<Question> initializeSymptomQuestions() {
        List<Question> symptomQuestions = new ArrayList<>();
        symptomQuestions.add(new Question(
                "症状采集",
                null,
                "是否有以下症状？",
                Arrays.asList(
                        "发热", "咽喉痛", "咳嗽", "鼻塞", "流鼻涕",
                        "胸闷", "气急", "呼吸困难", "全身酸痛", "乏力", "腹泻", "都没有"
                ),
                QuestionType.MULTI_EXCLUSIVE
        ));
        return symptomQuestions;
    }

    /**.
     * 初始化发热相关问题
     *
     * @return 发热相关问题列表
     */
    private List<Question> initializeFeverQuestions() {
        List<String> temperatureOptions = new ArrayList<>();
        // 使用整数作为循环计数器
        for (int i = MIN_TEMPERATURE_INT; i <= MAX_TEMPERATURE_INT; i++) {
            double temp = i / TEMPERATURE_DIVIDER;
            temperatureOptions.add(String.format("%.1f℃", temp));
        }

        return Arrays.asList(
                new Question("体温现状", "发热", "目前体温是多少？",
                        Arrays.asList("<37.3℃", "≥37.3℃"), QuestionType.SINGLE),
                new Question("最高体温", "发热", "最高体温是多少？", temperatureOptions, QuestionType.SINGLE),
                new Question("发热伴随症状", "发热", "发热时有没有以下情况？",
                        Arrays.asList("发热体温持续不退", "体温一直大于38℃", "都没有"), QuestionType.SINGLE),
                new Question("是否服药", "发热", "发热后有没有吃退热药？",
                        Arrays.asList("有吃退热药", "没有吃退热药"), QuestionType.SINGLE),
                new Question("服药后反应", "发热", "吃退热药后的体温情况是？",
                        Arrays.asList("体温下降", "体温下降又升高", "体温没有下降"), QuestionType.SINGLE)
        );
    }

    /**.
     * 初始化咳嗽相关问题
     *
     * @return 咳嗽相关问题列表
     */
    private List<Question> initializeCoughQuestions() {
        return Arrays.asList(
                new Question("咳嗽类型", "咳嗽", "有没有咳痰？",
                        Arrays.asList("没有咳痰（干咳）", "有咳痰"), QuestionType.SINGLE)
        );
    }

    /**.
     * 初始化腹泻相关问题
     *
     * @return 腹泻相关问题列表
     */
    private List<Question> initializeDiarrheaQuestions() {
        return Arrays.asList(
                new Question("腹泻加重", "腹泻", "有没有腹泻加重？",
                        Arrays.asList("有", "没有"), QuestionType.SINGLE)
        );
    }

    /**.
     * 初始化胸闷相关问题
     *
     * @return 胸闷相关问题列表
     */
    private List<Question> initializeChestTightnessQuestions() {
        return Arrays.asList(
                new Question("胸闷加重", "胸闷", "有没有胸闷加重？",
                        Arrays.asList("有", "没有"), QuestionType.SINGLE)
        );
    }

    /**.
     * 初始化气急相关问题
     *
     * @return 气急相关问题列表
     */
    private List<Question> initializeShortnessOfBreathQuestions() {
        return Arrays.asList(
                new Question("气急加重", "气急", "有没有气急加重？",
                        Arrays.asList("有", "没有"), QuestionType.SINGLE)
        );
    }

    /**.
     * 初始化症状时长问题
     *
     * @return 症状时长问题列表
     */
    private List<Question> initializeDurationQuestions() {
        return Arrays.asList(
                new Question("症状时长", null, "本次不舒服有多久了？",
                        Arrays.asList("14天以内", "14天以上"), QuestionType.SINGLE)
        );
    }

    /**.
     * 初始化接触史问题
     *
     * @return 接触史问题列表
     */
    private List<Question> initializeContactHistoryQuestions() {
        return Arrays.asList(
                new Question(
                        "接触史",
                        null,
                        "近14天有没有以下情况？",
                        Arrays.asList(
                                "有武汉（湖北）等疫区旅游史或居住史",
                                "有接触过武汉（湖北）等疫区的人员",
                                "有接触过疑似或确诊新型冠状病毒感染者",
                                "身边有多人出现发热、乏力、咳嗽、咽痛等",
                                "都没有"
                        ),
                        QuestionType.MULTI_EXCLUSIVE
                )
        );
    }

    /**.
     * 根据先前回答获取问题列表
     *
     * @param priorAnswer 先前的回答
     * @return 问题列表
     */
    public List<Question> getQuestions(String priorAnswer) {
        List<Question> questions = new ArrayList<>();
        if (priorAnswer == null) {
            return questionMap.get("症状采集");
        }
        switch (priorAnswer) {
            case "症状采集":
                questions.addAll(questionMap.get("症状采集"));
                break;
            case "发热":
                questions.addAll(questionMap.get("发热"));
                break;
            case "咳嗽":
                questions.addAll(questionMap.get("咳嗽"));
                break;
            case "腹泻":
                questions.addAll(questionMap.get("腹泻"));
                break;
            case "胸闷":
                questions.addAll(questionMap.get("胸闷"));
                break;
            case "气急":
                questions.addAll(questionMap.get("气急"));
                break;
            default: break;
        }
        questions.addAll(questionMap.get("症状时长"));
        questions.addAll(questionMap.get("接触史"));
        return questions;
    }

    /**.
     * 根据患者信息获取建议
     *
     * @param patientInfo 患者信息
     * @return 建议
     */
    public String getRecommendation(PatientInfo patientInfo) {
        Set<String> symptoms = patientInfo.getSymptoms();
        Set<String> contactHistory = patientInfo.getContactHistory();
        boolean hasSymptoms = !symptoms.contains("都没有") && symptoms.size() > 0;
        boolean hasContact = !contactHistory.contains("都没有") && contactHistory.size() > 0;

        if (hasSymptoms && hasContact) {
            return "建议立刻发热门诊就诊，并且佩戴好口罩做好防护。"
                    + "佩戴医用外科口罩或N95口罩，避免乘坐公共交通工具。";
        } else if (hasSymptoms) {
            return "结合你提供的病情症状及接触史特点，建议继续在家监测体温，"
                    + "可适当服用治疗感冒的中成药，注意手卫生，多饮水，休息为主。"
                    + "若体温持续不退或体温大于38℃或不适症状加重，及时就诊。";
        } else if (hasContact) {
            return "建议你们全家及密切接触者居家隔离至少2周，在家期间建议戴口罩交流，"
                    + "条件允许时，尽量单独居住或居住在通风良好的单人房间。"
                    + "多休息，多饮水，注意手卫生和常用物品卫生消毒。"
                    + "若出现发热及呼吸道症状，需马上前往医院就诊。";
        } else {
            return "建议您戴口罩、勤洗手，避免人群聚集，减少不必要外出。";
        }
    }

    /**.
     * 问题类型枚举
     */
    public enum QuestionType {
        SINGLE, MULTI_EXCLUSIVE
    }

    /**.
     * 问题类
     */
    public static class Question {
        private final String type;
        private final String questionText;
        private final List<String> options;

        /**.
         * 构造函数
         *
         * @param type           问题类型
         * @param priorCondition 前置条件
         * @param questionText   问题文本
         * @param options        选项列表
         * @param questionType   问题类型枚举
         */
        public Question(String type, String priorCondition, String questionText,
                        List<String> options, QuestionType questionType) {
            this.type = type;
            this.questionText = questionText;
            // 存储 options 的副本
            this.options = new ArrayList<>(options);
        }

        /**.
         * 获取问题类型
         *
         * @return 问题类型
         */
        public String getType() {
            return type;
        }

        /**.
         * 获取问题文本
         *
         * @return 问题文本
         */
        public String getQuestionText() {
            return questionText;
        }

        /**.
         * 获取选项列表
         *
         * @return 选项列表
         */
        public List<String> getOptions() {
            // 返回 options 的副本
            return new ArrayList<>(options);
        }
    }
}